﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyMathLib
{
    /// <summary>
    /// 最小二乘法
    /// </summary>
    public class MyMath
    {
        #region 
        /// <summary>
        /// 属性：X序列
        /// </summary>
        public List<double> X { get; set; }
        /// <summary>
        /// 属性：Y序列
        /// </summary>
        public List<double> Y { get; set; }
        /// <summary>
        /// 求X的平均值
        /// </summary>
        /// <returns></returns>
        public double AvgX => X == null || X.Count() == 0 ? 0 : X.Average();
        /// <summary>
        /// 求Y的平均值
        /// </summary>
        /// <returns></returns>
        public double AvgY => Y == null || Y.Count() == 0 ? 0 : Y.Average();
        /// <summary>
        /// (Xi - AvgX)
        /// </summary>
        /// <returns></returns>
        private List<double> x => X == null || X.Count() == 0 ? new List<double>() : X.Select(m => m - AvgX).ToList();
        /// <summary>
        /// (Yi - AvgY)
        /// </summary>
        /// <returns></returns>
        private List<double> y => Y == null || Y.Count() == 0 ? new List<double>() : Y.Select(m => m - AvgY).ToList();
        /// <summary>
        /// 属性：系数a
        /// </summary>
        private double a { get; set; }
        /// <summary>
        /// 属性：系数b
        /// </summary>
        private double b { get; set; }
        /// <summary>
        /// 计算a和b
        /// </summary>
        #endregion 
        public void Comput()
        {
            double result1 = 0;
            double result2 = 0;
            for (int i = 0; i < x.Count; i++)
            {
                result1 += x[i] * y[i];
                result2 += x[i] * x[i];
            }
            b = result1 / result2;
            a = AvgY - b * AvgX;
        }
        /// <summary>
        /// 预测函数
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        public double Forecast(double x)
        {
            return a + b * x;
        }
    }
}
